load("//tools/lint:lint.bzl", "add_lint_tests")
load(
    "//tools/skylark:drake_cc.bzl",
    "drake_cc_googletest",
    "drake_cc_library",
    "drake_cc_package_library",
)
load(
    "//tools/skylark:drake_optional.bzl",
    "drake_cc_optional_googletest",
    "drake_cc_optional_library",
)

package(default_visibility = ["//visibility:public"])

drake_cc_package_library(
    name = "mpm",
    visibility = ["//visibility:public"],
    deps = [
        ":bspline_weights",
        ":grid_data",
        ":mass_and_momentum",
        ":particle_data",
        ":particle_sorter",
        ":spgrid_flags",
    ],
)

drake_cc_library(
    name = "bspline_weights",
    srcs = [
        "bspline_weights.cc",
    ],
    hdrs = [
        "bspline_weights.h",
    ],
    deps = [
        "//common:essential",
        "//math:gradient",
    ],
)

drake_cc_library(
    name = "grid_data",
    hdrs = [
        "grid_data.h",
    ],
    deps = [
        "//common:autodiff",
        "//common:bit_cast",
        "//common:essential",
    ],
)

drake_cc_library(
    name = "mass_and_momentum",
    hdrs = [
        "mass_and_momentum.h",
    ],
    deps = [
        "//common:essential",
    ],
)

drake_cc_optional_library(
    name = "mock_sparse_grid",
    opt_in_condition = "//tools/skylark:linux",
    srcs = [
        "mock_sparse_grid.cc",
    ],
    hdrs = [
        "mock_sparse_grid.h",
    ],
    deps = [
        ":grid_data",
        ":mass_and_momentum",
        ":particle_data",
        ":particle_sorter",
        ":spgrid",
        "//multibody/contact_solvers/sap:partial_permutation",
    ],
)

drake_cc_library(
    name = "particle_data",
    srcs = [
        "particle_data.cc",
    ],
    hdrs = [
        "particle_data.h",
    ],
    deps = [
        ":mass_and_momentum",
        "//common:essential",
        "//common:parallelism",
        "//multibody/fem",
    ],
)

drake_cc_library(
    name = "particle_sorter",
    srcs = [
        "particle_sorter.cc",
    ],
    hdrs = [
        "particle_sorter.h",
    ],
    deps = [
        ":bspline_weights",
        ":spgrid_flags",
        "//common:essential",
        "//math:gradient",
    ],
)

# TODO(xuchenhan-tri): when we enable SPGrid in our releases, we also need to
# install its license file in drake/tools/workspace/BUILD.bazel.

drake_cc_optional_library(
    name = "sparse_grid",
    opt_in_condition = "//tools/skylark:linux",
    srcs = [
        "sparse_grid.cc",
    ],
    hdrs = [
        "sparse_grid.h",
    ],
    deps = [
        ":grid_data",
        ":mass_and_momentum",
        ":particle_data",
        ":particle_sorter",
        ":spgrid",
        "//multibody/contact_solvers/sap:partial_permutation",
    ],
)

drake_cc_optional_library(
    name = "mpm_model",
    opt_in_condition = "//tools/skylark:linux",
    srcs = [
        "mpm_model.cc",
        "solver_state.cc",
    ],
    hdrs = [
        "mpm_model.h",
        "solver_state.h",
    ],
    deps = [
        ":mock_sparse_grid",
        ":particle_data",
        ":sparse_grid",
        ":transfer",
        "//math:fourth_order_tensor",
        "//multibody/contact_solvers/sap:partial_permutation",
    ],
)

drake_cc_optional_library(
    name = "spgrid",
    opt_in_condition = "//tools/skylark:linux",
    srcs = [
        "spgrid.cc",
    ],
    hdrs = [
        "spgrid.h",
    ],
    defines = select({
        "//tools:using_memcheck": ["DRAKE_MPM_TESTING_LOG2_MAX_GRID_SIZE=5"],
        "//conditions:default": [],
    }),
    deps = [
        ":spgrid_flags",
        "//common:essential",
        "@spgrid_internal",
    ],
)

drake_cc_library(
    name = "spgrid_flags",
    hdrs = [
        "spgrid_flags.h",
    ],
    deps = [
        ":bspline_weights",
        "//common:essential",
        "//math:gradient",
    ],
)

drake_cc_optional_library(
    name = "transfer",
    opt_in_condition = "//tools/skylark:linux",
    srcs = [
        "transfer.cc",
    ],
    hdrs = [
        "transfer.h",
    ],
    deps = [
        ":mock_sparse_grid",
        ":particle_data",
        ":sparse_grid",
    ],
)

drake_cc_googletest(
    name = "bspline_weights_test",
    deps = [
        ":bspline_weights",
    ],
)

drake_cc_googletest(
    name = "grid_data_test",
    deps = [
        ":grid_data",
    ],
)

drake_cc_optional_googletest(
    name = "mpm_model_test",
    opt_in_condition = "//tools/skylark:linux",
    deps = [
        ":mpm_model",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_googletest(
    name = "particle_data_test",
    deps = [
        ":particle_data",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_optional_googletest(
    name = "particle_sorter_test",
    opt_in_condition = "//tools/skylark:linux",
    deps = [
        ":bspline_weights",
        ":grid_data",
        ":particle_data",
        ":particle_sorter",
        ":sparse_grid",
        ":spgrid",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_optional_googletest(
    name = "sparse_grid_test",
    opt_in_condition = "//tools/skylark:linux",
    deps = [
        ":mock_sparse_grid",
        ":sparse_grid",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

drake_cc_optional_googletest(
    name = "spgrid_test",
    opt_in_condition = "//tools/skylark:linux",
    deps = [
        ":spgrid",
        "//common/test_utilities:limit_malloc",
    ],
)

drake_cc_optional_googletest(
    name = "transfer_test",
    opt_in_condition = "//tools/skylark:linux",
    deps = [
        ":particle_data",
        ":sparse_grid",
        ":transfer",
        "//common/test_utilities:eigen_matrix_compare",
    ],
)

add_lint_tests()
